package handlers

import (
	"encoding/binary"
	"encoding/json"
	"errors"
	"fmt"
	"sync/atomic"
	"time"

	"github.com/RuiGuangServer/config"
	"github.com/RuiGuangServer/global"
	"github.com/RuiGuangServer/logs"
)

const (
	NetHeadSize  = 8      // 2+2+4=8字节头部
	NetStartSign = 0x55AA // 2字节起始标志
	HeaderType   = 12
)

type FlightPlanMessage struct {
	Type      string      `json:"type"`
	Data      *FlightPlan `json:"data"`
	Timestamp int64       `json:"timestamp"`
}

type FlightPlan struct {
	ID int64 `json:"id"`
	// 24位地址码
	AddressCode     *string `json:"addressCode"`
	CallSign        *string `json:"callSign"`
	SsrCode         *string `json:"ssrCode"`
	FlightRules     *string `json:"flightRules"`
	FlightType      *string `json:"flightType"`
	AircraftType    *string `json:"aircraftType"`
	WTC             *string `json:"wtc"`
	AidEquipment    *string `json:"aidEquipment"`
	SurEquipment    *string `json:"surEquipment"`
	ADEP            *string `json:"adep"`
	ADES            *string `json:"ades"`
	ADAR            *string `json:"adar"`
	ALTN1           *string `json:"altn1"`
	ALTN2           *string `json:"altn2"`
	TotalEET        *int64  `json:"totalEET"` // 以毫秒表示的总预计飞行时间
	FiledRoute      *string `json:"filedRoute"`
	OtherInfo       *string `json:"otherInfo"`
	EOBT            int64   `json:"eobt"` // 预计撤轮挡时间，Unix毫秒时间戳
	ETOT            int64   `json:"etot"` // 预计起飞时间，Unix毫秒时间戳
	ELDT            int64   `json:"eldt"` // 预计着陆时间，Unix毫秒时间戳
	EIBT            int64   `json:"eibt"` // 预计上轮挡时间，Unix毫秒时间戳
	AOBT            int64   `json:"aobt"` // 实际撤轮挡时间，Unix毫秒时间戳
	ATOT            int64   `json:"atot"` // 实际起飞时间，Unix毫秒时间戳
	ALDT            int64   `json:"aldt"` // 实际着陆时间，Unix毫秒时间戳
	AIBT            int64   `json:"aibt"` // 实际上轮挡时间，Unix毫秒时间戳
	SOBT            int64   `json:"sobt"` // 计划撤轮挡时间，Unix毫秒时间戳
	SIBT            int64   `json:"sibt"` // 计划上轮挡时间，Unix毫秒时间戳
	IOBT            int64   `json:"iobt"` // 初始撤轮挡时间，Unix毫秒时间戳
	ApprovedRoute   *string `json:"approvedRoute"`
	AirwayCodes     *string `json:"airwayCodes"`
	RegMarking      *string `json:"regMarking"`
	ApprovedArcType *string `json:"approvedArcType"`
	Jurisdiction    *string `json:"jurisdiction"`
	// 前序航班状态
	PreFlightState int32 `json:"preFlightState"`
	// 航班状态
	FlightState int32 `json:"flightState"`
	// 关联ID
	RefID *string `json:"refId"`
	// 关联航班
	PreFID      *string `json:"preFid"`
	CreatedTime int64   `json:"createdTime"` // 创建时间，Unix毫秒时间戳
}

// HandleFlightPlan 处理飞行计划消息（新版本，接收字节数据）
func HandleFlightPlan(data []byte, logger *logs.AsyncLogger, dataer *logs.AsyncLogger) error {
	if len(data) < NetHeadSize {
		return fmt.Errorf("incomplete header, expected %d bytes, got %d", NetHeadSize, len(data))
	}

	// 解析协议头
	startSign := binary.BigEndian.Uint16(data[0:2])
	msgType := binary.BigEndian.Uint16(data[2:4])
	totalLen := binary.BigEndian.Uint32(data[4:8])

	// 验证起始标志
	if startSign != NetStartSign {
		return fmt.Errorf("invalid start signature: expected 0x%X, got 0x%X", NetStartSign, startSign)
	}

	// 验证消息类型
	if msgType != HeaderType {
		return fmt.Errorf("unexpected message type: expected %d, got %d", HeaderType, msgType)
	}

	// 验证长度
	if totalLen < NetHeadSize || totalLen > uint32(len(data)) {
		return fmt.Errorf("invalid length: expected %d bytes, got %d", totalLen, len(data))
	}

	// 提取消息体
	body := data[NetHeadSize:totalLen]

	// 解析JSON消息
	var msg FlightPlanMessage
	if err := json.Unmarshal(body, &msg); err != nil {
		return fmt.Errorf("failed to parse flight plan message: %v", err)
	}

	dataer.Data("Flight plan message received: %+v", msg)

	switch msg.Type {
	case "fp":
		if err := processFlightPlan(msg, logger); err != nil {
			return fmt.Errorf("flight plan processing error: %v", err)
		}
	case "hb":
		logger.Debug("Heartbeat received at %v", time.Now().Format("2006-01-02 15:04:05"))
		// 心跳接收时间已通过TCP客户端自动更新，这里只需记录
	default:
		logger.Info("Unknown message type: %s", msg.Type)
	}

	return nil
}

func processFlightPlan(msg FlightPlanMessage, logger *logs.AsyncLogger) error {
	if msg.Data == nil {
		return errors.New("flight plan data is nil")
	}

	fp := msg.Data
	if fp.CallSign == nil {
		return errors.New("callsign is missing")
	}

	callSign := *fp.CallSign
	logger.Info("Processing flight plan: %s", callSign)

	if fp.ADEP == nil { //起飞机场
		return fmt.Errorf("ADEP missing for callsign: %s", callSign)
	}

	if fp.ADES == nil { //落地机场
		return fmt.Errorf("ADES missing for callsign: %s", callSign)
	}

	if fp.ALTN1 == nil { //第一备降机场
		return fmt.Errorf("ALTN1 missing for callsign: %s", callSign)
	}
	if fp.ALTN2 == nil { //第二备降机场
		return fmt.Errorf("ALTN2 missing for callsign: %s", callSign)
	}

	if *fp.ADEP != config.Config.AirPort && *fp.ADES != config.Config.AirPort && *fp.ALTN1 != config.Config.AirPort && *fp.ALTN2 != config.Config.AirPort {
		logger.Info("Skipping flight for other airport: %s", *fp.ADES)
		return nil
	}
	_DEP := ""
	_Etot := int64(0)
	if *fp.ADEP == config.Config.AirPort {
		_DEP = config.Config.AirPort
		_Etot = fp.ETOT / 1000
	}
	_DES := ""
	_Aldt := int64(0)
	if *fp.ADES == config.Config.AirPort || *fp.ALTN1 == config.Config.AirPort || *fp.ALTN2 == config.Config.AirPort {
		_DES = config.Config.AirPort
		_Aldt = fp.ALDT / 1000
	}

	// 获取或创建状态
	state, exists := global.PlanMap.Load(callSign)
	if !exists {
		state = &global.PlanState{
			CallSign: callSign,
			Source:   1,                 // 标记为飞行计划来源
			DEP:      _DEP,              // 出发地
			DES:      _DES,              // 目的地
			Etot:     _Etot,             // 预计起飞时间
			Aldt:     _Aldt,             // 预计着陆时间
			Utime:    time.Now().Unix(), // 接收数据时间
			Stime:    time.Now().Unix(), // 发送时间
		}
		global.PlanMap.Store(callSign, state)
		logger.Info("Created new track: %s", callSign)
	}

	// 检查数据源优先级
	if state.(*global.PlanState).Source > 1 {
		logger.Info("Higher priority source exists for: %s", callSign)
		return nil
	}

	// 更新状态
	planState := state.(*global.PlanState)

	// 更新目的地（如果未设置）
	if planState.DEP == "" {
		planState.DES = *fp.ADES
	}
	if planState.DEP == "" {
		planState.DEP = *fp.ADEP
	}
	if planState.Etot == 0 {
		planState.Etot = fp.ETOT
	}

	// 更新实际着陆时间（如果未设置）
	if planState.Aldt == 0 {
		planState.Aldt = fp.ALDT
	}

	// 确保来源标记正确
	if planState.Source != 1 {
		atomic.StoreInt32(&planState.Source, 1)
	}

	// 更新时间戳
	atomic.StoreInt64(&planState.Utime, time.Now().Unix())

	logger.Debug("Updated flight plan: %s", callSign)
	return nil
}

// createMessagePacket 创建消息包
func createMessagePacket(data []byte) []byte {
	msglen := uint32(len(data)) + NetHeadSize
	result := make([]byte, msglen)

	binary.BigEndian.PutUint16(result[0:2], NetStartSign)
	binary.BigEndian.PutUint16(result[2:4], HeaderType)
	binary.BigEndian.PutUint32(result[4:8], msglen)
	copy(result[NetHeadSize:], data)

	return result
}

// MsgFP 创建飞行计划消息
func MsgFP(typestr string, data any) []byte {
	msg := map[string]any{
		"Type": typestr,
		"Data": data,
	}
	jsonStr, _ := json.Marshal(msg)
	return createMessagePacket(jsonStr)
}
